package com.org.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.blockchain.API.TimeCoinAPI;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.org.mapper.CommunityAdminMapper;
import com.org.mapper.NormalUserMapper;
import com.org.pojo.CommunityAdmin;
import com.org.pojo.NormalUser;
import com.org.common.Result;
import com.org.pojo.Serve;
import com.org.pojo.TimeCoin;
import com.org.service.NormalUserService;
import com.org.service.ServeService;
import com.org.utils.ThreadLocalUtil;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * ClassName: TimeCoinController
 * Package: com.org.controller
 * Description:
 *
 * @Author Origin
 * @Create 2024/2/26 19:20
 * @Version 1.0
 */

@RestController
@RequestMapping("/timecoin")
public class TimeCoinController {

    @Autowired
    private NormalUserMapper normalUserMapper;

    @Autowired
    private CommunityAdminMapper communityAdminMapper;

    @Autowired
    private ServeService serveService;

    @Autowired
    private NormalUserService normalUserService;

    // 获取时间币数量
    @GetMapping("/getNum")
    public Result<Integer> getNum() throws Exception {

        Map<String, Object> m = ThreadLocalUtil.get();
        System.out.println(m);
        Integer id = (Integer) m.get("id");
        Integer userType = (Integer) m.get("userType");

//        if(userType == 1){
//            NormalUser n = normalUserMapper.selectById(id);
//            userPK = n.getChainKey();
//        }else if(userType == 0){
//            CommunityAdmin c = communityAdminMapper.selectById(id);
//            userPK = c.getChainKey();
//        }

        NormalUser user = normalUserMapper.selectById(id);
        if (user.getState().equals("时间币交易中")) {
            return Result.error("用户还有相关服务的时间币正在进行交易，请稍后");
        }
        String userPK = user.getChainKey();
        Integer numCoin = Integer.parseInt(TimeCoinAPI.balanceOfCoin(userPK, userPK));

        return Result.success(numCoin);
    }

    /**
     * 时间币核验
     * @param coinHash    时间币哈希值
     * @return          返回该时间币溯源信息
     * @throws Exception
     */
    @GetMapping("/verify")
    public Result<TimeCoin> traceability(String coinHash) { //时间币id
        Map<String, Object> m = ThreadLocalUtil.get();
        Integer id = (Integer) m.get("id");

        NormalUser user = normalUserMapper.selectById(id);
        if (user.getState().equals("时间币交易中")) {
            return Result.error("用户还有相关服务的时间币正在进行交易，请稍后");
        }
        String userPK = user.getChainKey();

        TimeCoin timeCoin = new TimeCoin();
        // 获取溯源信息的json串
        String coinInfo = null;
        try {
            coinInfo = TimeCoinAPI.getCoinInfoByHash(userPK, coinHash);
        } catch (Exception e) {
            return Result.error("时间币不存在");
        }
        // 设置时间币的哈希
        timeCoin.setCoinHash(coinHash);
        // 串转Json对象
        Gson gson = new GsonBuilder().setPrettyPrinting().create();
        JsonObject coinInfoJSON = gson.fromJson(coinInfo, JsonObject.class);
        // 单个币的溯源信息
        List<TimeCoin.TimeCoinInfo> infos = new ArrayList<>();
        // 单个币的交易次数
        int cnt = 0;
        // 设置单个币的溯源信息
        for(int i = 0; true; i++){
            if (coinInfoJSON.get(String.valueOf(i)) == null) {
                break;
            }
            // 单个币的单次交易信息
            String timeCoinInfoJSON = coinInfoJSON.get(String.valueOf(i)).toString();
            // json转java对象
            ObjectMapper mapper = new ObjectMapper();
            // 反序列化时间对象
            mapper.registerModule(new JavaTimeModule());
            mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
            // 转
            TimeCoin.TimeCoinInfo timeCoinInfo = null;
            try {
                timeCoinInfo = mapper.readValue(timeCoinInfoJSON, TimeCoin.TimeCoinInfo.class);
            } catch (JsonProcessingException e) {
                return Result.error("未知错误");
            }
            // 添加服务名称字段
            Serve serve = serveService.getOne(new LambdaQueryWrapper<Serve>().eq(Serve::getId, timeCoinInfo.getServiceId()));
            if(serve != null){
                timeCoinInfo.setServiceTitle(serve.getTitle());
            }
            // 添加单个币单条的溯源信息
            infos.add(timeCoinInfo);
            // 计数加一
            cnt++;
        }
        // 设置单个币溯源信息
        timeCoin.setInfos(infos);
        // 设置交易次数
        timeCoin.setTransferCnt(cnt - 1);
        return Result.success(timeCoin);
    }


    //查看自己所有的时间币信息
    @GetMapping("/detail")
    public Result<List<TimeCoin>> detail() throws Exception {
        Map<String, Object> m = ThreadLocalUtil.get();
        Integer id = (Integer) m.get("id");

        NormalUser user = normalUserMapper.selectById(id);
        if (user.getState().equals("时间币交易中")) {
            return Result.error("用户还有相关服务的时间币正在进行交易，请稍后");
        }
        String userPK = user.getChainKey();

        // 获取用户所拥有的时间币id的集合
        String coins = TimeCoinAPI.coinOfUser(userPK, userPK);
        System.out.println(coins);
        String[] coinIdAndHash = coins.split("@");
        String[] coinIds = coinIdAndHash[0].split(" ");
        String[] coinHashes = coinIdAndHash[1].split(" ");
        // 定义用户所拥有的时间币（返回值）
        List<TimeCoin> timeCoins = new ArrayList<>();
        // 获取用户所拥有的时间币的信息
        int index = 0; // 下表
        for(String s : coinIds){
            TimeCoin timeCoin = new TimeCoin();
            BigInteger cointId = BigInteger.valueOf(Integer.parseInt(s));
            // 设置时间币的id
            timeCoin.setCoinId(cointId);
            // 获取溯源信息的json串
            String coinInfo = TimeCoinAPI.getCoinInfo(userPK, cointId);
            // 串转Json对象
            Gson gson = new GsonBuilder().setPrettyPrinting().create();
            JsonObject coinInfoJSON = gson.fromJson(coinInfo, JsonObject.class);
            // 单个币的溯源信息
            List<TimeCoin.TimeCoinInfo> infos = new ArrayList<>();
            // 单个币的交易次数
            int cnt = 0;
            // 设置单个币的溯源信息
            for(int i = 0; true; i++){
                if (coinInfoJSON.get(String.valueOf(i)) == null) {
                    break;
                }
                // 单个币的单次交易信息
                String timeCoinInfoJSON = coinInfoJSON.get(String.valueOf(i)).toString();
                // json转java对象
                ObjectMapper mapper = new ObjectMapper();
                // 反序列化时间对象
                mapper.registerModule(new JavaTimeModule());
                mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
                // 转
                TimeCoin.TimeCoinInfo timeCoinInfo = mapper.readValue(timeCoinInfoJSON, TimeCoin.TimeCoinInfo.class);
                // 添加服务名称字段
                Serve serve = serveService.getOne(new LambdaQueryWrapper<Serve>().eq(Serve::getId, timeCoinInfo.getServiceId()));
                if(serve != null){
                    timeCoinInfo.setServiceTitle(serve.getTitle());
                }
                // 添加单个币单条的溯源信息
                infos.add(timeCoinInfo);
                // 计数加一
                cnt++;
            }
            // 设置时间币的哈希值
            timeCoin.setCoinHash(coinHashes[index++]);
            // 设置单个币溯源信息
            timeCoin.setInfos(infos);
            // 设置交易次数
            timeCoin.setTransferCnt(cnt - 1);
            // 添加到所有币的数组中
            timeCoins.add(timeCoin);
        }
        return Result.success(timeCoins);
    }

}
